#!/usr/bin/env ruby

#
# Implements minimalistic exportation and client over a plain unencrypted
# socket.
#

require 'socket'
require 'thread'

require 'simmon/logging'
require 'simmon/sensor'
require 'simmon/util'

module Simmon

  class SocketSensor < Sensor
    def initialize(remotename,
                   host,
                   port,
                   interval = 60,
                   maxlag = interval * 2,
                   initial_state = State.new(true))
      super("#{remotename}@#{host}", interval, maxlag, initial_state)
      
      @remotename = remotename
      @host = host
      @port = port

      @log = Log4r::Logger['simmon']
    end

    def sample()
      with_socket(TCPSocket.new(@host, @port)) do |s|
        Marshal.dump(@remotename, s)
        s.flush()
        Marshal.load(s)
      end
    end
  end

  class SocketExporter
    def initialize(port)
      @port = port

      @sensors = Hash.new()
      @mutex = Mutex.new()

      @log = Log4r::Logger['simmon']
    end
    
    def start()
      server = TCPServer.new(@port)

      @log.info("Listening on port #{@port}")

      begin
        while true do
          client = server.accept()
          Thread.new() do
            begin
              self.serve_client(client)
            rescue
              @log.warn("Serving client failed: #{$!}")
              raise
            end
          end
        end
      ensure
        server.close()
      end
    end

    def serve_client(client)
      @log.debug("Serving client (#{client.peeraddr[3]})")

      begin
        name = Marshal.load(client)
        
        Marshal.dump(sample_sensor(name), client)
        client.flush()
      ensure
        @log.debug("Client done (#{client.peeraddr[3]})")
      end
    end
    
    def register_sensor(sensor)
      @sensors[sensor.name()] = sensor
    end
    
    def sample_sensor(name)
      sensor = @sensors[name]
      
      if sensor then
        return sensor.state()
      else
        return State.new(false, nil, "sensor #{name} does not exist")
      end
    end
  end
end
